// Copyright (c) XiGuan 2023
// Author： xiguan
// Email: xiguan.teng@qq.com
// Create on 2023/10/19
// TODO:
//

#ifndef WEBSERVER_UTILS_BUFFER_H
#define WEBSERVER_UTILS_BUFFER_H

#include <atomic>
#include <string>
#include <vector>

class Buffer {
 private:
  std::vector<char> buffer_;

  std::atomic<std::size_t> read_pos_;
  std::atomic<std::size_t> write_pos_;

 public:
  Buffer(int _init_buffer_size = 1024);
  ~Buffer() = default;

  /**
   * @brief 返回可写区域的大小
   * @return
   */
  size_t WritableBytes() const;

  /**
   * @brief 可读区域的大小
   * @return
   */
  size_t ReadableBytes() const;

  size_t PrependableBytes() const;

  const char *Peek() const;

  void EnsureWriteable(size_t len);

  void HasWritten(size_t len);

  /**
   * @brief 回收可读区域
   * @param len 回收的大小
   */
  void Retrieve(size_t len);
  /**
   * @brief 回收可读区域, 一直遇到 end
   * @param end
   */
  void RetrieveUntil(const char *end);

  /**
   * @brief 全部回收
   */
  void RetrieveAll();

  /**
   * @brief 返回缓冲区数据，并回收全部
   * @return 缓冲区数据
   */
  std::string RetrieveAllToStr();

  /**
   * @brief 返回可写地址起点
   * @return
   */
  const char *BeginWriteConst() const;

  /**
   * @brief 返回可写地址起点
   * @return
   */
  char *BeginWrite();

  /**
   * @brief 把数据存入缓冲区
   * @param str
   */
  void Append(const std::string &str);
  void Append(const char *str, size_t len);
  void Append(const void *data, size_t len);
  void Append(const Buffer &buffer);

  // ssize_t  long
  // size_t   unsigned long
  ssize_t ReadFd(int fd, int *_errno);
  ssize_t WriteFd(int fd, int *_errno);

 private:
  char *BeginPtr_();

  const char *BeginPtr_() const;

  /**
   * @brief 回收缓冲区之前的空格
   * @param len
   */
  void MakeSpace_(size_t len);
};

#endif  // WEBSERVER_UTILS_BUFFER_H
